#!/usr/bin/env python
#
#

import datetime
import string
import re
import urllib

from base64 import b64encode
from xml.etree import ElementTree

from django.http import *
from django.shortcuts import render_to_response
from django.template import loader
from django.utils import simplejson
from django.core import serializers

from google.appengine.api import users
from google.appengine.api import urlfetch
from google.appengine.ext.db import GqlQuery
from google.appengine.ext import db

from models import *
import settings
import rest

views = {'view_home':'home',
         'add_user':'add_user',
         'view_channels':'channels',
         'view_new_channel':'new_channel',
         'view_channel':'channel',
         'view_campaigns':'campaigns',
         'view_campaign':'campaign',
         'view_new_campaign':'new_campaign',
         'view_messages':'messages',
         'view_new_message':'new_message',
         'view_message':'message',
         'view_contact':'contacts'
         }

### Decorators for request handlers ###

def login_required(func):
  """Decorator that redirects to the login page if you're not logged in."""
  def login_wrapper(request, *args, **kwds):
    if request.user is None:
      return HttpResponseRedirect(users.create_login_url("/"))
    return func(request, *args, **kwds)
  return login_wrapper

def get_context(func):
    def get_context_wrapper(request, *args, **kwds):
        request.context = views.copy()
        request.context['user'] = request.user
        request.userprofile = UserProfile.get_by_user(request.user)
        return func(request, *args, **kwds)
    return get_context_wrapper

#######################################

def login(request, url=None):
    if url:
        return HttpResponsePermanentRedirect(users.create_login_url(url))
    if request.environ.has_key('HTTP_REFERER'):
        return HttpResponsePermanentRedirect(users.create_login_url(request.environ['HTTP_REFERER']))
    return HttpResponseRedirect(users.create_login_url("/"))
  
def logout(request):
    if request.environ.has_key('HTTP_REFERER'):
        return HttpResponsePermanentRedirect(users.create_logout_url(request.environ['HTTP_REFERER']))
    return HttpResponseRedirect(users.create_logout_url("/"))

#######################################

@login_required
@get_context
def root(request):
    companies = Company.get_by_user(request.userprofile)
    request.context['companies'] = companies
    return render_to_response('socialcrm/home.html', request.context)

@login_required
@get_context
def register(request):
    if request.POST:
        if 'company_id' in request.POST and 'company_name' in request.POST:
            company = Company(name=request.POST['company_id'], company_name=request.POST['company_name'],
                              users=[request.userprofile.key()], admins=[request.userprofile.key()])
            company.put()
            return HttpResponseRedirect("/%s/" % company.name)
    return render_to_response('socialcrm/new_company.html', request.context)

#######################################

@login_required
@get_context
def view(request, company_name, view_1, view_2=None, view_3=None):
    if view_2 and view_3:
        handler = '%s_%s_%s' % (view_1, view_2, view_3)
    elif view_2:
        handler = '%s_%s' % (view_1, view_2)
    else:
        handler = view_1
        
    handler = globals().get(handler)
    if handler:
        return handler(request, company_name)
    raise Http404

@login_required
@get_context
def details(request, company_name, id, view_1, view_2=None, view_3=None):
    if view_2 and view_3:
        handler = '%s_%s_%s' % (view_1, view_2, view_3)
    elif view_2:
        handler = '%s_%s' % (view_1, view_2)
    else:
        handler = view_1
        
    handler = globals().get(handler)
    if handler:
        return handler(request, company_name, id)
    raise Http404

@login_required
@get_context
def home(request, company_name):
    company = Company.get_by_user(request.userprofile, company_name)
    if company.name == company_name:
        request.context['company'] = company
        request.context['admins'] = db.get(company.admins)
        return render_to_response('socialcrm/company.html', request.context)
    #FIXME use urlresolver to find root path
    return HttpResponseRedirect("/socialcrm/")

@login_required
@get_context
def add_user(request, company_name):
    company = Company.get_by_user(request.userprofile, company_name)
    if company and request.POST:
        if 'email' in request.POST and request.POST['email']:
            user = UserProfile.get_by_email(request.POST['email'])
            if user:
                company.admins.append(user.key())
            company.put()
            return HttpResponseRedirect("/socialcrm/%s/" % company.name)
    return render_to_response('socialcrm/new_user.html', request.context)

@login_required
@get_context
def contacts(request, company_name):
    company = Company.get_by_user(request.userprofile, company_name)
    if company.name == company_name:
        request.context['company'] = company
        request.context['contacts'] = Contact.get_all_by_company(company)
        return render_to_response('socialcrm/contacts.html', request.context)
    return HttpResponseRedirect("/socialcrm/")

@login_required
@get_context
def channels(request, company_name):
    company = Company.get_by_user(request.userprofile, company_name)
    if company.name == company_name:
        request.context['company'] = company
        request.context['channels'] = Channel.get_all_by_company(company)
        return render_to_response('socialcrm/channels.html', request.context)
    return HttpResponseRedirect("/socialcrm/")

@login_required
@get_context
def new_channel(request, company_name):
    company = Company.get_by_user(request.userprofile, company_name)
    if not company or company.name != company_name:
        return HttpResponseRedirect("/socialcrm/%s/" % company.name)
    if request.POST:
        if 'channel_name' in request.POST and request.POST['channel_name']\
            and 'channel_type' in request.POST and request.POST['channel_type']:
            channel = Channel(company=company, name=request.POST['channel_name'], 
                              type=request.POST['channel_type'])
            channel.put()
            return HttpResponseRedirect("/socialcrm/channel/%s/" % (company.name, channel.key().id()))
    return render_to_response('socialcrm/new_channel.html', request.context)

@login_required
@get_context
def channel(request, company_name, channel_id):
    company = Company.get_by_user(request.userprofile, company_name)
    if not company or company.name != company_name:
        return HttpResponseRedirect("/socialcrm/%s/" % company.name)
    channel = Channel.get_by_id(int(channel_id))
    if channel and channel.company.key()==company.key():
        request.context['company'] = company
        request.context['channel'] = channel
        return render_to_response('socialcrm/channel_%s.html'%channel.type, request.context)
    return HttpResponseRedirect("/socialcrm/%s/channels/" % (company.name))


@login_required
@get_context
def campaigns(request, company_name):
    company = Company.get_by_user(request.userprofile, company_name)
    if company.name == company_name:
        request.context['company'] = company
        request.context['campaigns'] = Campaign.get_all_by_company(company)
        return render_to_response('socialcrm/campaigns.html', request.context)
    return HttpResponseRedirect("/socialcrm/")

@login_required
@get_context
def new_campaign(request, company_name):
    company = Company.get_by_user(request.userprofile, company_name)
    if not company or company.name != company_name:
        return HttpResponseRedirect("/socialcrm/%s/" % company.name)
    if request.POST:
        if 'campaign_name' in request.POST and request.POST['campaign_name']:
            campaign = Campaign(company=company, name=request.POST['campaign_name'])
            campaign.put()
            return HttpResponseRedirect("/socialcrm/%s/campaign/%s/" % (company.name, campaign.key().id()))
    return render_to_response('socialcrm/new_campaign.html', request.context)

@login_required
@get_context
def campaign(request, company_name, campaign_id):
    company = Company.get_by_user(request.userprofile, company_name)
    if not company or company.name != company_name:
        return HttpResponseRedirect("/socialcrm/%s/" % company.name)
    campaign = Campaign.get_by_id(int(campaign_id))
    if campaign and campaign.company.key()==company.key():
        request.context['company'] = company
        request.context['campaign'] = campaign
        return render_to_response('socialcrm/campaign.html', request.context)
    return HttpResponseRedirect("/socialcrm/%s/campaigns/" % (company.name))

@login_required
@get_context
def campaign_messages(request, company_name, campaign_id):
    company = Company.get_by_user(request.userprofile, company_name)
    if not company or company.name != company_name:
        return HttpResponseRedirect("/socialcrm/%s/" % company.name)
    campaign = Campaign.get_by_id(int(campaign_id))
    if campaign and campaign.company.key()==company.key():
        request.context['company'] = company
        request.context['campaign'] = campaign
        request.context['messages'] = CampaignMessage.get_all_by_campaign(campaign)
        return render_to_response('socialcrm/campaign_messages.html', request.context)
    return HttpResponseRedirect("/socialcrm/%s/campaigns/" % (company.name))

@login_required
@get_context
def campaign_messages_new_message(request, company_name, campaign_id):
    company = Company.get_by_user(request.userprofile, company_name)
    if not company or company.name != company_name:
        return HttpResponseRedirect("/socialcrm/%s/" % company.name)
    campaign = Campaign.get_by_id(int(campaign_id))
    if campaign and request.POST:
        if 'name' in request.POST and request.POST['name']\
            and 'content' in request.POST and request.POST['content']:
            message = CampaignMessage(campaign=campaign, name=request.POST['name'], content=request.POST['content'])
            message.put()
            return HttpResponseRedirect("/socialcrm/%s/message/%s/" % (company.name, message.key().id()))
    return render_to_response('socialcrm/new_message.html', request.context)



@login_required
@get_context
def message(request, company_name, message_id):
    company = Company.get_by_user(request.userprofile, company_name)
    if not company or company.name != company_name:
        return HttpResponseRedirect("/socialcrm/%s/" % company.name)
    message = CampaignMessage.get_by_id(int(message_id))
    if message and message.campaign.company.key()==company.key():
        request.context['company'] = company
        request.context['campaign'] = message.campaign
        request.context['message'] = message
        request.context['channels'] = Channel.get_all_by_company(company)
        return render_to_response('socialcrm/message.html', request.context)
    return HttpResponseRedirect("/socialcrm/%s/campaigns/" % (company.name))

@rest.model(Company, 'company')
def contact_view():
    pass